package home

import (
	"adai.design/homeserver/devices"
	"adai.design/homeserver/log"
	"adai.design/homeserver/members"
	"adai.design/homeserver/db"
	"github.com/globalsign/mgo/bson"
)

type Hub struct {
	homes 		map[string]*Home

	devRec 		chan *devices.MessagePkg
	devSend		chan *devices.MessagePkg

	memberRec	chan *members.MessagePkg
	memberSend 	chan *members.MessagePkg
}

func (h *Hub) Handle(pkg *devices.MessagePkg) {
	if h.devRec != nil {
		h.devRec <- pkg
	}
}

func (h *Hub) HandleMemberPkg(pkg *members.MessagePkg) {
	if h.memberRec != nil {
		h.memberRec <- pkg
	}
}

func (h *Hub) start(end chan bool) {
	hub.devRec = make(chan *devices.MessagePkg, 10)
	hub.devSend = make(chan *devices.MessagePkg, 10)
	hub.memberRec = make(chan *members.MessagePkg, 10)
	hub.memberSend = make(chan *members.MessagePkg, 10)

	devices.AddObserver(h)
	members.AddObserver(h)

	defer func() {
		devices.RemoveObserver(h)
		members.RemoveObserver(h)
	}()

	for {
		select {
		case pkg, ok := <- h.devRec:
			if ok {
				//log.Debug("container(%s)->home(%s) message(%s)", pkg.DevId, pkg.HomeId, pkg.Msg.String())
				if home, ok := h.homes[pkg.HomeId]; ok {
					home.receiveContainerPkg(pkg)
				}
			}

		case pkg, ok := <- h.devSend:
			if ok {
				//log.Debug("home(%s)->container(%s) message(%s)", pkg.HomeId, pkg.DevId, pkg.Msg.String())
				devices.SendPackage(pkg)
			}

		case pkg, ok := <-h.memberRec:
			if ok {
				if home, ok := h.homes[pkg.Ctx.HomeId]; ok {
					home.receiveMemberPkg(pkg)
				}
			}

		case pkg, ok := <-h.memberSend:
			if ok {
				members.SendPackage(pkg)
			}
		}
	}
	end <- true
}

var hub = &Hub{}

func Establish(end chan bool) {
	hub.homes = make(map[string]*Home, 0)

	session, collection := db.GetHomeSession()
	if collection == nil {
		log.Fatal("mongodb server 404 not found")
	}
	defer session.Close()

	var hs []*Home
	err := collection.Find(bson.M{}).All(&hs)
	if err != nil {
		return
	}

	for _, h := range hs {
		log.Info("home id(%s)", h.Id)
		hub.homes[h.Id] = h
		go h.run(hub)
	}

	go hub.start(end)
}

